import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.text.MaskFormatter;
import javax.swing.text.DefaultStyledDocument.ElementBuffer;


public class Dictionary {
	private HashMap<String, DictElement> dict = new HashMap<String, DictElement>();
	private final static Collection<String> emptyCollection = Collections.unmodifiableCollection(new ArrayList<String>());
	public class NullElement extends DictElement {
		
		public NullElement(String master) {
			super(master);
			// TODO Auto-generated constructor stub
		}

		

		@Override
		public Integer getSlaveNumber(String slave) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public Collection<String> getSlaveCollection() {
			// TODO Auto-generated method stub
			return emptyCollection;
		}

		@Override
		public int getElementRang() {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return master;
		}
		
		
		
	}
	public class DictElement {
		
		//private String slave;
		private HashMap<String, Integer> slaveMap = new HashMap<String, Integer>();
		private int elementRang = 0;
		protected String master;
		public DictElement (String master) {
			this.master = master;
			
		
		}
		public String getMaster() {
			return this.master;
		}
		public void addSlave(String slave, int number) {
			elementRang += number;
			if (slaveMap.containsKey(slave)) {
				slaveMap.put(slave, slaveMap.get(slave) + number);
				return;				
			}
			slaveMap.put(slave, number);
			
		}
		public Integer getSlaveNumber(String slave) {
			Integer ret  = slaveMap.get(slave);
			if (ret == null) {
				return 0;
			}
			return ret;
		}
		public Collection<String> getSlaveCollection() {
			return slaveMap.keySet();
		}
		
		public int getElementRang() {
			return elementRang;
		}
		@Override
		public boolean equals(Object obj) {
			// TODO Auto-generated method stub
			DictElement element = (DictElement)obj;
			return element.master.equals(master);
			//return super.equals(obj);
		}
		@Override
		public int hashCode() {
			// TODO Auto-generated method stub
			return super.hashCode();
			
		}
		public String toString() {
			String res = "";
			for (String slaves : getSlaveCollection()) {
				res +=  "," + slaves;
			}
			return "(" + master + ":" + res + ")";
			
		}
		
	}
	
	public void add(String master, String slave, int numberOf) {
		master = Util.getStem(master);
		slave = Util.getStem(slave);
		if (!dict.containsKey(master)) {
			DictElement newElem = new DictElement(master);
			newElem.addSlave(slave, numberOf);
			dict.put(master, newElem);
		} else {
			
			dict.get(master).addSlave(slave, numberOf);
		}
		
		
	}
	public int getNumber(String master, String slave) {
		return dict.get(master).getSlaveNumber(slave);
	}
	public Collection<String> getSlaves(String master) {
		DictElement elem =  dict.get(master);
		if (elem != null) {
			return Collections.unmodifiableSet(dict.get(master).slaveMap.keySet());
		}
		else {
			return null;
		}
		
	}
	public DictElement getElementByMaster(String master) {
		DictElement ret = dict.get(master);
		if (ret == null)  {
			return new NullElement(master);
		}
		return ret;
	}
	public Dictionary () {
		
	}
	
  
}
